package com.sangshen.ad_suyi_flutter_sdk;

import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.List;

import cn.admobiletop.adsuyi.ad.ADSuyiBannerAd;
import cn.admobiletop.adsuyi.ad.ADSuyiNativeAd;
import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeAdInfo;
import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeExpressAdInfo;
import cn.admobiletop.adsuyi.ad.entity.ADSuyiAdSize;
import cn.admobiletop.adsuyi.ad.entity.ADSuyiExtraParams;
import cn.admobiletop.adsuyi.ad.error.ADSuyiError;
import cn.admobiletop.adsuyi.ad.listener.ADSuyiNativeAdListener;
import cn.admobiletop.adsuyi.util.ADSuyiAdUtil;
import cn.admobiletop.adsuyi.util.ADSuyiDisplayUtil;
import cn.admobiletop.adsuyi.util.ADSuyiViewUtil;
import io.flutter.plugin.platform.PlatformView;

public class FlutterNativeAd extends FlutterAd implements PlatformView, FlutterDestroyableAd {

    @NonNull
    private final AdInstanceManager manager;
    /**
     * 广告位id
     */
    @NonNull
    private final String adPosId;
    /**
     * 场景id可选
     */
    @NonNull
    private final String sceneId;
    /**
     * 广告宽
     */
    @NonNull
    private final int adWidth;
    /**
     * 广告高
     */
    @NonNull
    private final int adHeight;
    /**
     * 广告容器
     */
    private FrameLayout flContainer;
    /**
     * 广告对象
     */
    private ADSuyiNativeAd adSuyiNativeAd;

    static class Builder {
        @Nullable
        private AdInstanceManager manager;
        @Nullable
        private String adPosId;
        @Nullable
        private String sceneId;
        @Nullable
        private Double adWidth;
        @Nullable
        private Double adHeight;

        public Builder setManager(@NonNull AdInstanceManager manager) {
            this.manager = manager;
            return this;
        }

        public Builder setAdPosId(@NonNull String adPosId) {
            this.adPosId = adPosId;
            return this;
        }

        public Builder setAdWidth(@NonNull Double adWidth) {
            this.adWidth = adWidth;
            return this;
        }

        public Builder setAdHeight(@NonNull Double adHeight) {
            this.adHeight = adHeight;
            return this;
        }

        public Builder setSceneId(@NonNull String sceneId) {
            this.sceneId = sceneId;
            return this;
        }

        FlutterNativeAd build() {
            if (manager == null) {
                throw new IllegalStateException("AdInstanceManager cannot not be null.");
            } else if (adPosId == null) {
                throw new IllegalStateException("adPosId cannot not be null.");
            }

            final FlutterNativeAd nativeAd = new FlutterNativeAd(manager, adPosId, sceneId, adWidth, adHeight);
            return nativeAd;
        }
    }

    private FlutterNativeAd(
            @NonNull AdInstanceManager manager, @NonNull String adPosId, @NonNull String sceneId, @NonNull Double adWidth, @NonNull Double adHeight) {
        this.manager = manager;
        this.adPosId = adPosId;
        this.sceneId = sceneId;
        this.adWidth = ADSuyiDisplayUtil.dp2px(new Double(adWidth).intValue());
        this.adHeight = 0;

        flContainer = new FrameLayout(manager.activity);

    }

    @Override
    void load() {
        // 创建信息流广告实例
        adSuyiNativeAd = new ADSuyiNativeAd(manager.activity);
        // 创建额外参数实例
        ADSuyiExtraParams extraParams = new ADSuyiExtraParams.Builder()
                // 设置整个广告视图预期宽高(目前仅头条平台需要，没有接入头条可不设置)，单位为px，高度如果小于等于0则高度自适应
                .adSize(new ADSuyiAdSize(adWidth, adHeight))
                // 设置广告视图中MediaView的预期宽高(目前仅Inmobi平台需要,Inmobi的MediaView高度为自适应，没有接入Inmobi平台可不设置)，单位为px
                .nativeAdMediaViewSize(new ADSuyiAdSize((int) (adWidth - 24 * manager.activity.getResources().getDisplayMetrics().density)))
                // 设置信息流广告适配播放是否静音，默认静音，目前广点通、百度、汇量、快手、Admobile支持修改
                .nativeAdPlayWithMute(ADSuyiDemoConstant.NATIVE_AD_PLAY_WITH_MUTE)
                .build();
        // 设置一些额外参数，有些平台的广告可能需要传入一些额外参数，如果有接入头条、Inmobi平台，如果包含这些平台该参数必须设置
        adSuyiNativeAd.setLocalExtraParams(extraParams);

        // 设置仅支持的广告平台，设置了这个值，获取广告时只会去获取该平台的广告，null或空字符串为不限制，默认为null，方便调试使用，上线时建议不设置
        adSuyiNativeAd.setOnlySupportPlatform(ADSuyiDemoConstant.NATIVE_AD_ONLY_SUPPORT_PLATFORM);
        // 设置广告监听
        adSuyiNativeAd.setListener(new ADSuyiNativeAdListener() {
            @Override
            public void onRenderFailed(ADSuyiNativeAdInfo adSuyiNativeAdInfo, ADSuyiError adSuyiError) {
                Log.d(ADSuyiDemoConstant.TAG, "onRenderFailed: " + adSuyiError.toString());
                if (adSuyiError != null) {
                    Log.d(ADSuyiDemoConstant.TAG, "onAdFailed: " + adSuyiError.toString());
                    manager.onAdFailed(FlutterNativeAd.this, adSuyiError);
                }
            }

            @Override
            public void onAdReceive(List<ADSuyiNativeAdInfo> adInfoList) {
                Log.d(ADSuyiDemoConstant.TAG, "onAdReceive: " + adInfoList.size());
                manager.onAdReceive(FlutterNativeAd.this);
                if (adInfoList != null && adInfoList.size() > 0) {
                    ADSuyiNativeAdInfo adSuyiNativeAdInfo = adInfoList.get(0);
                    if (adSuyiNativeAdInfo instanceof ADSuyiNativeExpressAdInfo) {
                        showNativeAd((ADSuyiNativeExpressAdInfo) adSuyiNativeAdInfo);
                    }
                }
            }

            @Override
            public void onAdExpose(ADSuyiNativeAdInfo adSuyiNativeAdInfo) {
                Log.d(ADSuyiDemoConstant.TAG, "onAdExpose: " + adSuyiNativeAdInfo.hashCode());
                manager.onAdExpose(FlutterNativeAd.this);
            }

            @Override
            public void onAdClick(ADSuyiNativeAdInfo adSuyiNativeAdInfo) {
                Log.d(ADSuyiDemoConstant.TAG, "onAdClick: " + adSuyiNativeAdInfo.hashCode());
                manager.onAdClick(FlutterNativeAd.this);
            }

            @Override
            public void onAdClose(ADSuyiNativeAdInfo adSuyiNativeAdInfo) {
                Log.d(ADSuyiDemoConstant.TAG, "onAdClose: " + adSuyiNativeAdInfo.hashCode());
                manager.onAdClose(FlutterNativeAd.this);
            }

            @Override
            public void onAdFailed(ADSuyiError adSuyiError) {
                if (adSuyiError != null) {
                    Log.d(ADSuyiDemoConstant.TAG, "onAdFailed: " + adSuyiError.toString());
                    manager.onAdFailed(FlutterNativeAd.this, adSuyiError);
                }
            }
        });
        adSuyiNativeAd.loadAd(adPosId);
    }

    private void showNativeAd(ADSuyiNativeExpressAdInfo nativeExpressAdInfo) {
        if (!ADSuyiAdUtil.adInfoIsRelease(nativeExpressAdInfo)) {
//            NativeAdAdapter.setVideoListener(nativeExpressAdInfo);
            // 当前是信息流模板广告，getNativeExpressAdView获取的是整个模板广告视图
            final View nativeExpressAdView = nativeExpressAdInfo.getNativeExpressAdView(flContainer);
            // 将广告视图添加到容器中的便捷方法
            ADSuyiViewUtil.addAdViewToAdContainer(flContainer, nativeExpressAdView);

            // 渲染广告视图, 必须调用, 因为是模板广告, 所以传入ViewGroup和响应点击的控件可能并没有用
            // 务必在最后调用
            nativeExpressAdInfo.render(flContainer);

            if ("gdt".equals(nativeExpressAdInfo.getPlatform())) {
                manager.onNativeReceived(FlutterNativeAd.this
                        , adWidth
                        , ADSuyiDisplayUtil.px2dp(adWidth * 9 / 10)
                );
            } else {
                int[] size = unDisplayViewSize(flContainer);
                manager.onNativeReceived(FlutterNativeAd.this, adWidth, size[1]);
            }
        }
    }

    @Override
    public void release() {
        if (adSuyiNativeAd != null) {
            adSuyiNativeAd.release();
            adSuyiNativeAd = null;
        }
        flContainer.removeAllViews();
    }

    @Override
    public View getView() {
        return flContainer;
    }

    @Override
    public void dispose() {

    }

    public int[] unDisplayViewSize(View view) {
        int size[] = new int[2];
        int width = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        int height = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        view.measure(width, height);
        size[0] = view.getMeasuredWidth();
        size[1] = ADSuyiDisplayUtil.px2dp(view.getMeasuredHeight());

        Log.d("unDisplayViewSize", "width:" + width + " height:" + height);
        Log.d("unDisplayViewSize", "width:" + view.getMeasuredWidth() + " height:" + view.getMeasuredHeight());
        return size;
    }
}
